package org.light.generator;

import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Util;

public class PDFUtilGenerator extends Util{
	public PDFUtilGenerator(){
		super();
		super.fileName = "POIExcelUtil.java";
	}
	
	public PDFUtilGenerator(String packageToken){
		super();
		this.setPackageToken(packageToken);
		super.fileName = "PDFUtil.java";
	}
	
	@Override
	public void setPackageToken(String packageToken) {
		this.packageToken = packageToken;
	}
	
	@Override
	public String generateUtilString() {
		StatementList sList = new StatementList();
		sList.add(new Statement(1000L,0, "package "+this.packageToken+".utils;"));
		sList.add(new Statement(2000L,0,""));
		sList.add(new Statement(3000L,0,"import java.awt.image.BufferedImage;"));
		sList.add(new Statement(4000L,0,"import java.io.ByteArrayInputStream;"));
		sList.add(new Statement(5000L,0,"import java.io.IOException;"));
		sList.add(new Statement(6000L,0,"import java.io.InputStream;"));
		sList.add(new Statement(7000L,0,"import java.io.OutputStream;"));
		sList.add(new Statement(8000L,0,"import java.util.ArrayList;"));
		sList.add(new Statement(9000L,0,"import java.util.List;"));
		sList.add(new Statement(10000L,0,""));
		sList.add(new Statement(11000L,0,"import javax.imageio.ImageIO;"));
		sList.add(new Statement(12000L,0,""));
		sList.add(new Statement(13000L,0,"import com.itextpdf.text.BaseColor;"));
		sList.add(new Statement(14000L,0,"import com.itextpdf.text.Document;"));
		sList.add(new Statement(15000L,0,"import com.itextpdf.text.Font;"));
		sList.add(new Statement(16000L,0,"import com.itextpdf.text.Image;"));
		sList.add(new Statement(17000L,0,"import com.itextpdf.text.PageSize;"));
		sList.add(new Statement(18000L,0,"import com.itextpdf.text.Paragraph;"));
		sList.add(new Statement(19000L,0,"import com.itextpdf.text.Rectangle;"));
		sList.add(new Statement(20000L,0,"import com.itextpdf.text.pdf.BaseFont;"));
		sList.add(new Statement(21000L,0,"import com.itextpdf.text.pdf.PdfPCell;"));
		sList.add(new Statement(22000L,0,"import com.itextpdf.text.pdf.PdfPTable;"));
		sList.add(new Statement(23000L,0,"import com.itextpdf.text.pdf.PdfWriter;"));
		sList.add(new Statement(24000L,0,""));
		sList.add(new Statement(25000L,0,"public final class PDFUtil {"));
		sList.add(new Statement(26000L,1,"private static boolean containsImage(List<Boolean> isImages) {"));
		sList.add(new Statement(27000L,2,"for (Boolean isImage : isImages) {"));
		sList.add(new Statement(28000L,3,"if (isImage) return true;"));
		sList.add(new Statement(29000L,2,"}"));
		sList.add(new Statement(30000L,2,"return false;"));
		sList.add(new Statement(31000L,1,"}"));
		sList.add(new Statement(32000L,0,""));
		sList.add(new Statement(33000L,1,"public static void exportPDFWithImage(OutputStream out, String sheetName, List<String> headers, List<List<Object>> contents,List<Boolean> isImages)"));
		sList.add(new Statement(34000L,3,"throws Exception {"));
		sList.add(new Statement(35000L,2,"BaseFont bfChinese = BaseFont.createFont(\"STSong-Light\", \"UniGB-UCS2-H\", BaseFont.NOT_EMBEDDED);"));
		sList.add(new Statement(36000L,2,"Font fontChinese = new Font(bfChinese, 12, Font.NORMAL);"));
		sList.add(new Statement(37000L,2,"Font fontChineseBold = new Font(bfChinese, 12, Font.BOLD);"));
		sList.add(new Statement(38000L,2,"Rectangle rectPageSize = new Rectangle(PageSize.A4);"));
		sList.add(new Statement(39000L,2,"Document document = new Document(rectPageSize, 50, 50, 50, 50);"));
		sList.add(new Statement(40000L,2,"if (headers.size() > 10||containsImage(isImages)) {"));
		sList.add(new Statement(41000L,3,"document.setPageSize(rectPageSize.rotate());"));
		sList.add(new Statement(42000L,2,"}"));
		sList.add(new Statement(43000L,2,"PdfWriter.getInstance(document, out);"));
		sList.add(new Statement(44000L,2,"document.open();"));
		sList.add(new Statement(45000L,2,""));
		sList.add(new Statement(46000L,2,"BaseColor headback = new BaseColor(180,180,180);"));
		sList.add(new Statement(47000L,2,"BaseColor whiteback = new BaseColor(255,255,255);"));
		sList.add(new Statement(48000L,0,""));
		sList.add(new Statement(49000L,2,"PdfPTable table = new PdfPTable(headers.size());"));
		
		sList.add(new Statement(49100L,2,"int imageCounts = 0;"));
		sList.add(new Statement(49200L,2,"if (contents.size()>0) imageCounts = countImages(contents.get(0));"));
		
		sList.add(new Statement(50000L,2,"float cellWidth = (rectPageSize.getHeight()-200)/(headers.size()+2*imageCounts);"));
		sList.add(new Statement(51000L,2,"List<Float> list = buildCellWidthList(isImages,cellWidth);"));
		sList.add(new Statement(52000L,2,"float [] cellWidthArr = new float[list.size()];"));
		sList.add(new Statement(53000L,2,"for (int i=0;i<list.size();i++) {"));
		sList.add(new Statement(54000L,3,"cellWidthArr[i] = list.get(i);"));
		sList.add(new Statement(55000L,2,"}"));
		sList.add(new Statement(56000L,2,"table.setWidths(cellWidthArr);"));
		sList.add(new Statement(57000L,2,"//table.setLockedWidth(true);"));
		sList.add(new Statement(58000L,2,"writeRow(table, fontChineseBold, headback, headers);"));
		sList.add(new Statement(59000L,0,""));
		sList.add(new Statement(60000L,2,"for (List<Object> data : contents) {"));
		sList.add(new Statement(61000L,3,"writeRowWithImage(table, fontChinese, whiteback,data,cellWidth);"));
		sList.add(new Statement(62000L,2,"}"));
		sList.add(new Statement(63000L,2,"document.add(table);"));
		sList.add(new Statement(64000L,2,"document.close();"));
		sList.add(new Statement(65000L,1,"}"));
		sList.add(new Statement(66000L,1,""));
		sList.add(new Statement(67000L,1,"private static List<Float> buildCellWidthList(List<Boolean> isImages,float cellWidth) {"));
		sList.add(new Statement(68000L,2,"List<Float> result = new ArrayList<>();"));
		sList.add(new Statement(69000L,2,"for (boolean isImage:isImages) {"));
		sList.add(new Statement(70000L,3,"if (isImage) result.add(3*cellWidth);"));
		sList.add(new Statement(71000L,3,"else result.add(cellWidth);"));
		sList.add(new Statement(72000L,2,"}"));
		sList.add(new Statement(73000L,2,"return result;"));
		sList.add(new Statement(74000L,1,"}"));
		sList.add(new Statement(75000L,0,""));
		sList.add(new Statement(76000L,1,"private static int countImages(List<Object> data ) {"));
		sList.add(new Statement(77000L,2,"int retVal = 0;"));
		sList.add(new Statement(78000L,2,"for (Object o:data) {"));
		sList.add(new Statement(79000L,3,"if (o instanceof byte []) retVal ++;"));
		sList.add(new Statement(80000L,2,"}"));
		sList.add(new Statement(81000L,2,"return retVal;"));
		sList.add(new Statement(82000L,1,"}"));
		sList.add(new Statement(83000L,0,""));
		
		sList.add(new Statement(84000L,1,"private static int getPercent(float h,float w, float cellWidth) {"));
		sList.add(new Statement(85000L,2,"float p2 =  3.0f*cellWidth / w * 100;"));
		sList.add(new Statement(86000L,2,"return Math.round(p2);"));
		sList.add(new Statement(87000L,1,"}"));

		sList.add(new Statement(93000L,1,""));
		sList.add(new Statement(94000L,1,"protected static void writeRow(PdfPTable table, Font fontChinese, BaseColor color,List<String> data) throws Exception{"));
		sList.add(new Statement(95000L,2,"for (int j = 0; j < data.size(); j++) {"));
		sList.add(new Statement(96000L,3,"PdfPCell cell = new PdfPCell();"));
		sList.add(new Statement(97000L,3,"cell.setBackgroundColor(color);"));
		sList.add(new Statement(98000L,3,"cell.addElement(new Paragraph(data.get(j),fontChinese));"));
		sList.add(new Statement(99000L,3,"table.addCell(cell);"));
		sList.add(new Statement(100000L,2,"}"));
		sList.add(new Statement(101000L,1,"}"));
		sList.add(new Statement(102000L,1,""));
		sList.add(new Statement(103000L,1,"public static BufferedImage getBufferedImage(byte[] image) {"));
		sList.add(new Statement(104000L,2,"BufferedImage bi = null;"));
		sList.add(new Statement(105000L,2,"try {"));
		sList.add(new Statement(106000L,3,"InputStream buffin = new ByteArrayInputStream(image);"));
		sList.add(new Statement(107000L,3,"bi = ImageIO.read(buffin);"));
		sList.add(new Statement(108000L,2,"} catch (IOException e) {"));
		sList.add(new Statement(109000L,3,"e.printStackTrace();"));
		sList.add(new Statement(110000L,2,"}"));
		sList.add(new Statement(111000L,2,"return bi;"));
		sList.add(new Statement(112000L,1,"}"));
		sList.add(new Statement(113000L,1,""));
		sList.add(new Statement(114000L,1,"protected static void writeRowWithImage(PdfPTable table, Font fontChinese, BaseColor color,List<Object> data,float cellWidth)  throws Exception{"));
		sList.add(new Statement(115000L,3,"for (int j = 0; j < data.size(); j++) {"));
		sList.add(new Statement(116000L,3,"PdfPCell cell = new PdfPCell();"));
		sList.add(new Statement(117000L,3,"cell.setBackgroundColor(color);"));
		sList.add(new Statement(118000L,3,"if (data.get(j) instanceof String)cell.addElement(new Paragraph((String)data.get(j),fontChinese));"));
		sList.add(new Statement(119000L,3,"else if (data.get(j) instanceof byte[]) {"));
		sList.add(new Statement(120000L,4,"if (data.get(j)!=null) {"));
		sList.add(new Statement(121000L,5,"BufferedImage bi = getBufferedImage((byte[])data.get(j));"));
		sList.add(new Statement(122000L,5,"if (bi!=null) {"));
		sList.add(new Statement(123000L,6,"Image image = Image.getInstance(bi,null);"));
		sList.add(new Statement(124000L,6,"if (image!=null && image.getWidth()>0&& image.getHeight()>0) {"));
		sList.add(new Statement(125000L,7,"image.setAlignment(Image.ALIGN_CENTER);"));
		sList.add(new Statement(126000L,7,"image.scalePercent(getPercent(image.getHeight(),image.getWidth(),cellWidth));"));
		sList.add(new Statement(127000L,7,"cell.addElement(image);"));
		sList.add(new Statement(128000L,6,"}"));
		sList.add(new Statement(129000L,5,"}"));
		sList.add(new Statement(130000L,4,"}"));
		sList.add(new Statement(131000L,3,"}"));
		sList.add(new Statement(132000L,3,"table.addCell(cell);"));
		sList.add(new Statement(133000L,2,"}"));
		sList.add(new Statement(134000L,1,"}"));
		sList.add(new Statement(135000L,0,"}"));

		return sList.getContent();
	}

}
